from django.contrib import messages
from django.shortcuts import redirect, render

from accounts.models import Account
from .forms import ForgetpasswdForm, LoginForm, NewPasswordForm, RegistForm
from django.contrib.auth import authenticate, login, logout
from .tokens import VerifyToken
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from .tasks import send_email

# Create your views here.

def home_view(request):
    return render(request, 'account/index.html')

def regist_view(request):
    if request.method == 'POST':
        regist_form = RegistForm(request.POST)
        
        if regist_form.is_valid():
            username = regist_form.cleaned_data['username']
            email = regist_form.cleaned_data['email']
            first_name = regist_form.cleaned_data['first_name']
            last_name = regist_form.cleaned_data['last_name']
            password = regist_form.cleaned_data['password']

            new_account = Account.objects.create(
                username=username, 
                email=email,
                first_name = first_name,
                last_name = last_name,
            )

            new_account.set_password(password)
            # Set verify token here
            new_account.token = VerifyToken.token_generator(
                {
                    'id': new_account.pk,
                    'username': username,
                }
            )
            
            # set user not active
            new_account.is_active = False
            new_account.save()

            # send activate emial here.
            current_site = get_current_site(request)
            mail_subject = 'Activate your account'
            message = render_to_string(
                'email/activate_email.html',
                {
                    'user': new_account,
                    'domain': current_site,
                    'token': new_account.token,
                }
            )

            send_email.delay(mail_subject, message, [email,])

            return render(request, 'account/info.html', {
                'info': 'Success! please activate your account from E-mail.'})
        else:
            return render(request, 'account/form.html', {'form': regist_form, 'title': 'Register'})

    form = RegistForm()
    return render(request, 'account/form.html', {'form': form, 'title': 'Register'})

def login_view(request):
    if request.method == 'POST':
        login_form = LoginForm(request.POST)

        if login_form.is_valid():
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']

            user = None
            if Account.objects.filter(username=username):
                user = authenticate(username=username, password=password)
            else:
                username_database = Account.objects.get(email=username)
                user = authenticate(username=username_database, password=password)

            if user is not None:
                login(request, user)
                return redirect('home')
            else:
                messages.warning(request, 'Invalid password!')
                return render(request, 'account/form.html', {'form': login_form, 'title': 'Login'})
        else:
            return render(request, 'account/form.html', {'form': login_form, 'title': 'Login'})

    form = LoginForm()
    return render(request, 'account/form.html', {'form': form, 'title': 'Login'})

def logout_view(request):
    logout(request)
    return render(request, 'account/index.html')

def activate_view(request, token):
    try:
        data = VerifyToken.token_decode(token)
        account = Account.objects.get(pk=data['id'])
    except Exception as e:
        return render(request, 'account/info.html', {'info': 'Invalid request!'})
    
    if account is not None and account.token == token:
        account.is_active = True
        account.token = ''
        account.save()
        return redirect('login')

    # return 404 or something else.
    return render(request, 'account/info.html', {'info': 'Bad request'})

def forget_password_view(request):
    if request.method == 'POST':
        forget_form = ForgetpasswdForm(request.POST)
        if forget_form.is_valid():
            email = forget_form.cleaned_data['email']
            account = Account.objects.get(email=email)
            payload = {
                'id': account.pk,
                'email': email,
            }
            token = VerifyToken.token_generator(payload)
            account.token = token
            account.save()

            # send verify links use get with token
            return render(request, 'account/info.html', {'info': 'Please reset your password from link recieved by E-mail.'})
        else:
            return render(request, 'account/form.html', {'form': forget_form, 'title': 'Forget Passwd'})


    token = request.GET.get('token')
    if token is not None:
        try:
            data = VerifyToken.token_decode(token)
            account = Account.objects.get(pk=data['id'])
        except Exception as e:
            return render(request, 'account/info.html', {'info': 'Invalid token!'})
        
        if account is not None and account.token == token:
            # account.token = ''
            # account.save()
            form = NewPasswordForm()
            return render(request, 'account/form.html', {'form': form, 'title': 'Forget Passwd'})

    form = ForgetpasswdForm()
    return render(request, 'account/form.html', {'form': form, 'title': 'Forget Passwd'})

def new_password_view(request):
    if request.method == 'POST':
        form = NewPasswordForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data['email']
            password = form.cleaned_data['new_password']
            account = Account.objects.get(email=email)
            
            account.token = ''
            account.set_password(password)
            account.save()
            
            return redirect('login')
        else:
            return render(request, 'account/form.html', {'form': form, 'title': 'New password'})
    # return 404 or something else.
    return render(request, 'account/info.html', {'info': 'Bad request'})